/*
 * Copyright (c) 2017-2019, Lindenis Tech. Ltd.
 * All rights reserved.
 *
 * File:
 *
 * Description:
 *
 * Author:
 *      xiaoshujun@lindeni.com
 *
 * Create Date:
 *      2020/08/17
 *
 * History:
 *
 */

#ifndef __LIND_RPC_H__
#define __LIND_RPC_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "osal_types.h"

#define PKG_DATA_HEAD               "LINDDATA"
#define PKG_HELLO                   "hello"
#define PKG_NIHAO                   "nihao, Welcome to lindeni!"
#define PKG_FAILED                  "failed"
#define PKG_OK                      "ok"
#define PKG_SIZE                    "size"
#define PKG_UNKNOWN                 "unknown"

#define PACKAGE_SIZE_MAX        4096

#define CONNECT_TIMEOU_S        3
#define SOCK_RECV_TIMEOUT_MS    3000
#define HEART_DEAD_CNT          10          // 10*3000ms = 30s

typedef enum _rpc_msg_e
{
    RPC_MSG_UNKNOWN             = 0,

    // msg callback
    RPC_MSG_DEVICE_IN,
    RPC_MSG_DEVICE_OUT,
    RPC_MSG_NEW_PARCEL,
    RPC_MSG_RAW_DATA,
    RPC_MSG_NO_HEART,
} rpc_msg_e;

typedef struct _rpc_config_t
{
    net_addr_t      server_addr;
    int             i_enable_heart;
    uint8_t         aes_key[16];
    uint8_t         aes_iv[16];
    comm_msg_cb     cb;
    void *          user;

    /*
     * if set '1', it will create a thread to listen remote command
     * only one of server or device should be set '1'.
     */
    uint8_t         i_listener;

    /*
     * if use 4G AT net
     */
    int             use_at;
    char            tty_node[128];
} rpc_config_t;

typedef struct _rpc_dev_t
{
    int32_t         sock;
    net_addr_t      addr;
} rpc_dev_t;

/**
 * rpc server
 */
_handle_t rpcs_create();
void rpcs_destroy(_handle_t h_rpcs);
int  rpcs_start(_handle_t h_rpcs, rpc_config_t * p_config);
int  rpcs_stop(_handle_t h_rpcs);

/**
 * rpc client
 */
_handle_t rpcc_create();
void rpcc_destroy(_handle_t h_rpcc);
int  rpcc_start(_handle_t h_rpcc, rpc_config_t * p_config);
int  rpcc_stop(_handle_t h_rpcc);
int  rpcc_standby(_handle_t h_rpcc);
int  rpcc_resume(_handle_t h_rpcc);

/**
 * rpc common
 */
int rpc_recv_crypto(int fd, uint8_t * p_buffer, int size_max, int flag);
int rpc_send_crypto(int fd, uint8_t * p_buffer, int size, int flag);
int rpc_send_recv_timeout(int fd,
                          char * p_send, int send_size,
                          char * p_recv, int recv_size,
                          int time_out_cnt);

int rpc_recv_raw(int fd, uint8_t * p_buffer, int * size, int left_size);

#ifdef __cplusplus
}
#endif

#endif  // __LIND_RPC_H__

